package top.java.commonClass;

import org.junit.Test;

/**
 *          关于    String           StringBuffer                StringBuilder
 *                 1.0              1.0                         1.5
 *                 不可变的字符序列    可变的字符序列                 可变的字符序列
 *                 效率最差          线程安全，效率较低(同步方法)      线程不安全，效率较高
 *          三者底层都使用char[]存储
 *          作为参数传递的话，方法内部String不会改变其值，StringBuffer和StringBuilder会改变其值。
 */

public class StringTest5 {

    @Test
    public void test1() {
        StringBuffer sbf = new StringBuffer("abc");
        sbf.setCharAt(1,'a');
        System.out.println(sbf);                    //aac
        String s = sbf + "aaa";
        System.out.println(s);                      //aacaaa
    }

    /**
     *
     *
     */

    @Test
    public void test2() {
        //char[] value = new char[0]
        String s1 = new String();

        //char[] value = new char[]{'a','b','c'}
        String str1 = new String("abc");

        //char[] value = new char[16]  底层创建了长度为16的char数组
        StringBuffer sbf1 = new StringBuffer();

        //value[0] = 'a'
        sbf1.append("a");                   //append()  向此 Appendable 添加指定字符。

        //value[1] = 'b'
        sbf1.append("b");

        //char value = new char["abc".length + 16]
        StringBuffer sbf2 = new StringBuffer("abc");

        System.out.println(sbf2.length());          //3     存储字符的个数而非容量

        /**
         *      扩容机制：
         *          StringBuffer默认长度为16
         *         当添加的数据底层数组盛不下时，扩容为原来的 << 1 + 2 (2倍+2) 并将原数据复制到新数组中
         *         如扩容之后仍然盛不下，则将该数组的地址赋值给value
         *
         *         指导意义：开发中如果字符串需要经常变换，则建议使用 StringBuffer 或者 StringBuilder
         *         再根据线程是否安全使用其一
         *         如果知道字符的大概长度，则使用带长度的参数构造器，避免扩容影响效率
         */
    }

    /**
     *      对比String,StringBuffer,StringBuilder 效率对比
     */
    @Test
    public void test3() {
        //初始设置
        long startTime = 0L;
        long endTime = 0L;
        String text = "";
        StringBuffer buffer = new StringBuffer("");
        StringBuilder builder = new StringBuilder("");
        //开始对比
        startTime = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            buffer.append(String.valueOf(i));
        }
        endTime = System.currentTimeMillis();
        System.out.println("StringBuffer的执行时间：" + (endTime - startTime));
        startTime = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            builder.append(String.valueOf(i));
        }
        endTime = System.currentTimeMillis();
        System.out.println("StringBuilder的执行时间：" + (endTime - startTime));
        startTime = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            text = text + i;
        }
        endTime = System.currentTimeMillis();
        System.out.println("String的执行时间：" + (endTime - startTime));

    }
}
